package me.dengfengdecao.android.photogallery;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Message;
import android.util.Log;
import android.widget.ImageView;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;

/**
 * 后台线程，处理缩略图的下载
 * imageView:标识每一次下载
 */
public class ThumbnailDownloader extends HandlerThread {

    private static final String TAG = "ThumbnailDownloader";
    private static final int MESSAGE_DOWNLOAD = 0;  // 消息的what属性

	private LrcCacheUtils mLrcCacheUtils;
	private Listener<ImageView> mListener;

	private Handler mHandler;        // 存放当前线程的handler
    private Handler mResponseHandler; // 存放来自于主线程的Handler

    private Map<ImageView, String> mRequest;    // key:ImageView value:picUrl

    // 初始化主线程的Handler,以访问与主线程Looper绑定的Handler
    public ThumbnailDownloader(Handler responseHandler) {
        super(TAG);
	    mLrcCacheUtils = LrcCacheUtils.newInstance();
        mResponseHandler = responseHandler;
	    mRequest = Collections.synchronizedMap(new HashMap<ImageView, String>());
    }

    /**
     * 获取并发送消息给它的目标Handler
     * @param imageView 用ImageView来标识
     * @param picUrl 缩略图的URL
     */
    public void queueThumbnail(ImageView imageView, String picUrl) {
	    if (imageView == null) return;

	    // 使用imageView作为key，可存储或获取与特定imageView相关联的图片URL。
        mRequest.put(imageView, picUrl);
        // 创建信息并传入其他消息字段,发送到消息队列。自动完成目标Handler的创建
        mHandler.obtainMessage(MESSAGE_DOWNLOAD, imageView).sendToTarget();
    }

    /**
     * 该方法的调用发生在Looper第一次检查消息队列之前，所以该方法成了我们创建Handler实现的好地方
     * what 用户定义的int型消息代码，用来描述消息；
     * obj 随消息发送的用户指定对象；
     * target 处理消息的Handler
     */
    @Override
    protected void onLooperPrepared() {
       mHandler = new Handler() {
           // 检查消息类型，获取imageView，然后将其传递给handleRequest(...)方法
           @Override
           public void handleMessage(Message msg) {
                if (msg.what == MESSAGE_DOWNLOAD) {
                    ImageView imageView = (ImageView) msg.obj;  // 类型擦除
                    Log.d(TAG, "onLooperPrepared 根据键imageView获得缩略图URL的值：" + mRequest.get(imageView));
                    handleRequest(imageView);
                }
           }
       };

    }

	/**
	 * 处理下载的缩略图,并通过自定义监听器mListener更新UI
	 * @param imageView mRequest的key
	 */
    private void handleRequest(final ImageView imageView) {
        // 得到图片地址
        final String picUrl = mRequest.get(imageView);

        if (picUrl == null) return;

	    // 先从缓存中取图片
	    final Bitmap bitmapCache = mLrcCacheUtils.getBitmapFromMemoryCache(picUrl);
	    // 存在图片则显示,否则根据缩略图url去下载
	    if (bitmapCache != null) {
	        mResponseHandler.post(new Runnable() {
	            @Override
	            public void run() {
	                mRequest.remove(imageView);
	                mListener.onThumbnailDownloaded(imageView, bitmapCache, picUrl);
	                Log.d(TAG, "handleRequest 缓存中的位图已设置到imageView上！");
	            }
	        });
	    } else {
	        byte[] bytes = new NetFetcher().getPicUrlBytes(picUrl); // 得到图片地址的字节数组
            if (bytes == null) {
                Log.d(TAG, "handleRequest: bytes数组为空!");
                return;
            }

	        final Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, 0, bytes.length); // 将返回的字节数组转换为位图
		    mLrcCacheUtils.addBitmapToMemoryCache(picUrl, bitmap); // 如果缓存中没有图片则将其存入缓存中
	        // 导致Runnable被添加到消息队列。Runnable将在附加Handler的线程上运行。
	        mResponseHandler.post(new Runnable() {
	            @Override
	            public void run() {
	                // 从mRequest中删除imageView，然后将bitmap设置到imageView上。
	                mRequest.remove(imageView);
	                mListener.onThumbnailDownloaded(imageView, bitmap, picUrl);
	                Log.d(TAG, "handleRequest 下载的位图已设置到imageView上！");
	            }
	        });
	    }
    }

    public void setListener(Listener<ImageView> listener) {
        mListener = listener;
    }

    // 一个用来通信的监听器接口，用来更新UI
    public interface Listener<ImageView> {
        void onThumbnailDownloaded(ImageView imageView, Bitmap thumbnail, String picUrl);
    }

    // 设备旋转导致ImageView失效时，清除等待队列的所有请求
    public void clearQueue() {
        mHandler.removeMessages(MESSAGE_DOWNLOAD);
        // 清空Map
        mRequest.clear();
    }

    @Override
    public boolean quit() {
        if (mLrcCacheUtils != null) {
	        mLrcCacheUtils.cleerMemoryCache();
            Log.w(TAG, "quit 线程已退出且已清理缓存！");
        }
        return super.quit();
    }
}
